package com.icongyou.enterprise.talent_pool.service.impl;

import com.icongyou.enterprise.common.result.PageResult;
import com.icongyou.enterprise.data_aggregation.entity.UserEntity;
import com.icongyou.enterprise.data_aggregation.service.DataAggregationService;
import com.icongyou.enterprise.talent_pool.entity.vo.CoreSubmissionVO;
import com.icongyou.enterprise.talent_pool.entity.vo.StudentTalentVO;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class StudentTalentServiceImplTest {

    @Mock
    private DataAggregationService dataAggregationService;

    @InjectMocks
    private StudentTalentServiceImpl studentTalentService;

    private UserEntity userEntity1;
    private UserEntity userEntity2;
    private final String studentId1 = "student-123";
    private final String studentId2 = "student-456";
    private final String tenantId = "tenant-123";

    @BeforeEach
    void setUp() {
        // 初始化测试数据
        userEntity1 = new UserEntity();
        userEntity1.setId(studentId1);
        userEntity1.setRealName("张三");
        userEntity1.setAvatar("avatar1.jpg");
        userEntity1.setMajor("计算机科学");
        userEntity1.setRanking(1);
        userEntity1.setTenantId(tenantId);

        userEntity2 = new UserEntity();
        userEntity2.setId(studentId2);
        userEntity2.setRealName("李四");
        userEntity2.setAvatar("avatar2.jpg");
        userEntity2.setMajor("软件工程");
        userEntity2.setRanking(2);
        userEntity2.setTenantId(tenantId);
    }

    @Test
    void getStudentTalents_WithDefaultParameters_ShouldReturnAllStudents() {
        // 准备数据
        List<UserEntity> userEntities = Arrays.asList(userEntity1, userEntity2);
        when(dataAggregationService.getStudentsWithPagination(0, 10)).thenReturn(userEntities);
        when(dataAggregationService.getTenantNameByUserId(anyString())).thenReturn("清华大学");
        when(dataAggregationService.countStudentsByMajor(eq(tenantId), anyString())).thenReturn(100);
        when(dataAggregationService.getCoreSubmission(anyString())).thenReturn(new CoreSubmissionVO());

        // 执行方法
        PageResult<StudentTalentVO> result = studentTalentService.getStudentTalents(null, null, null, null, null);

        // 验证
        assertNotNull(result);
        assertEquals(2, result.getList().size());
        assertEquals(2, result.getTotal());
        assertEquals(1, result.getPage());
        assertEquals(10, result.getSize());

        verify(dataAggregationService, times(2)).getTenantNameByUserId(anyString());
        verify(dataAggregationService, times(2)).countStudentsByMajor(eq(tenantId), anyString());
    }

    @Test
    void getStudentTalents_WithTeacherRecommendedFilter_ShouldFilterStudents() {
        // 准备数据
        List<UserEntity> userEntities = Arrays.asList(userEntity1, userEntity2);
        when(dataAggregationService.getStudentsWithPagination(0, 10)).thenReturn(userEntities);
        when(dataAggregationService.getTenantNameByUserId(anyString())).thenReturn("清华大学");
        when(dataAggregationService.countStudentsByMajor(eq(tenantId), anyString())).thenReturn(100);
        when(dataAggregationService.getCoreSubmission(anyString())).thenReturn(new CoreSubmissionVO());

        // 设置第一个学生被教师推荐，第二个不被推荐
        when(dataAggregationService.isTeacherRecommended(studentId1)).thenReturn(true);
        when(dataAggregationService.isTeacherRecommended(studentId2)).thenReturn(false);

        // 执行方法 - 只查询被教师推荐的学生
        PageResult<StudentTalentVO> result = studentTalentService.getStudentTalents(null, null, true, null, null);

        // 验证
        assertNotNull(result);
        assertEquals(1, result.getList().size());
        assertEquals(studentId1, result.getList().get(0).getStudentId());
    }

    @Test
    void getStudentTalents_WithCoreTaskTop30Filter_ShouldFilterStudents() {
        // 准备数据
        List<UserEntity> userEntities = Arrays.asList(userEntity1, userEntity2);
        when(dataAggregationService.getStudentsWithPagination(0, 10)).thenReturn(userEntities);
        when(dataAggregationService.getTenantNameByUserId(anyString())).thenReturn("清华大学");
        when(dataAggregationService.countStudentsByMajor(eq(tenantId), anyString())).thenReturn(100);
        when(dataAggregationService.getCoreSubmission(anyString())).thenReturn(new CoreSubmissionVO());

        // 设置第一个学生在核心任务前30%，第二个不在
        when(dataAggregationService.isCoreTaskTop30(studentId1)).thenReturn(true);
        when(dataAggregationService.isCoreTaskTop30(studentId2)).thenReturn(false);

        // 执行方法 - 只查询核心任务前30%的学生
        PageResult<StudentTalentVO> result = studentTalentService.getStudentTalents(null, null, null, true, null);

        // 验证
        assertNotNull(result);
        assertEquals(1, result.getList().size());
        assertEquals(studentId1, result.getList().get(0).getStudentId());
    }

    @Test
    void getStudentTalents_WithHighPotentialFilter_ShouldFilterStudents() {
        // 准备数据
        List<UserEntity> userEntities = Arrays.asList(userEntity1, userEntity2);
        when(dataAggregationService.getStudentsWithPagination(0, 10)).thenReturn(userEntities);
        when(dataAggregationService.getTenantNameByUserId(anyString())).thenReturn("清华大学");
        when(dataAggregationService.countStudentsByMajor(eq(tenantId), anyString())).thenReturn(100);
        when(dataAggregationService.getCoreSubmission(anyString())).thenReturn(new CoreSubmissionVO());

        // 设置第一个学生有高潜力成果，第二个没有
        when(dataAggregationService.hasHighPotentialSubmission(studentId1)).thenReturn(true);
        when(dataAggregationService.hasHighPotentialSubmission(studentId2)).thenReturn(false);

        // 执行方法 - 只查询有高潜力成果的学生
        PageResult<StudentTalentVO> result = studentTalentService.getStudentTalents(null, null, null, null, true);

        // 验证
        assertNotNull(result);
        assertEquals(1, result.getList().size());
        assertEquals(studentId1, result.getList().get(0).getStudentId());
    }

    @Test
    void getStudentTalents_WithMultipleFilters_ShouldApplyAllFilters() {
        // 准备数据
        List<UserEntity> userEntities = Arrays.asList(userEntity1, userEntity2);
        when(dataAggregationService.getStudentsWithPagination(0, 10)).thenReturn(userEntities);
        when(dataAggregationService.getTenantNameByUserId(anyString())).thenReturn("清华大学");
        when(dataAggregationService.countStudentsByMajor(eq(tenantId), anyString())).thenReturn(100);
        when(dataAggregationService.getCoreSubmission(anyString())).thenReturn(new CoreSubmissionVO());

        // 设置第一个学生满足所有条件
        when(dataAggregationService.isTeacherRecommended(studentId1)).thenReturn(true);
        when(dataAggregationService.isCoreTaskTop30(studentId1)).thenReturn(true);
        when(dataAggregationService.hasHighPotentialSubmission(studentId1)).thenReturn(true);

        // 第二个学生不满足某些条件
        when(dataAggregationService.isTeacherRecommended(studentId2)).thenReturn(false);
        when(dataAggregationService.isCoreTaskTop30(studentId2)).thenReturn(true);
        when(dataAggregationService.hasHighPotentialSubmission(studentId2)).thenReturn(true);

        // 执行方法 - 应用所有过滤器
        PageResult<StudentTalentVO> result = studentTalentService.getStudentTalents(null, null, true, true, true);

        // 验证
        assertNotNull(result);
        assertEquals(1, result.getList().size());
        assertEquals(studentId1, result.getList().get(0).getStudentId());
    }

    @Test
    void getStudentTalents_WithCustomPagination_ShouldApplyPagination() {
        // 准备数据
        List<UserEntity> userEntities = Collections.singletonList(userEntity1);
        when(dataAggregationService.getStudentsWithPagination(20, 5)).thenReturn(userEntities);
        when(dataAggregationService.getTenantNameByUserId(anyString())).thenReturn("清华大学");
        when(dataAggregationService.countStudentsByMajor(eq(tenantId), anyString())).thenReturn(100);
        when(dataAggregationService.getCoreSubmission(anyString())).thenReturn(new CoreSubmissionVO());

        // 执行方法 - 第5页，每页5条
        PageResult<StudentTalentVO> result = studentTalentService.getStudentTalents(5, 5, null, null, null);

        // 验证
        assertNotNull(result);
        assertEquals(1, result.getList().size());
        assertEquals(5, result.getPage());
        assertEquals(5, result.getSize());
        verify(dataAggregationService).getStudentsWithPagination(20, 5); // (5-1)*5 = 20
    }

    @Test
    void getStudentTalents_WithCoreSubmission_ShouldSetCoreSubmission() {
        // 准备数据
        List<UserEntity> userEntities = Collections.singletonList(userEntity1);
        CoreSubmissionVO coreSubmission = new CoreSubmissionVO();
        coreSubmission.setSubmissionId("core-submission-123");
        coreSubmission.setAssignmentName("核心项目");
        coreSubmission.setScore(95.0);

        when(dataAggregationService.getStudentsWithPagination(0, 10)).thenReturn(userEntities);
        when(dataAggregationService.getTenantNameByUserId(anyString())).thenReturn("清华大学");
        when(dataAggregationService.countStudentsByMajor(eq(tenantId), anyString())).thenReturn(100);
        when(dataAggregationService.getCoreSubmission(studentId1)).thenReturn(coreSubmission);

        // 执行方法
        PageResult<StudentTalentVO> result = studentTalentService.getStudentTalents(null, null, null, null, null);

        // 验证
        assertNotNull(result);
        assertEquals(1, result.getList().size());

        StudentTalentVO studentTalent = result.getList().get(0);
        assertNotNull(studentTalent.getCoreSubmission());
        assertEquals("core-submission-123", studentTalent.getCoreSubmission().getSubmissionId());
        assertEquals("核心项目", studentTalent.getCoreSubmission().getAssignmentName());
        assertEquals(95.0, studentTalent.getCoreSubmission().getScore());
    }

    @Test
    void convertToStudentTalentVO_ShouldConvertCorrectly() throws Exception {
        // 准备数据
        when(dataAggregationService.getTenantNameByUserId(studentId1)).thenReturn("清华大学");
        when(dataAggregationService.countStudentsByMajor(tenantId, "计算机科学")).thenReturn(150);
        when(dataAggregationService.getCoreSubmission(studentId1)).thenReturn(new CoreSubmissionVO());

        // 使用反射直接调用私有方法
        Method method = StudentTalentServiceImpl.class
                .getDeclaredMethod("convertToStudentTalentVO", UserEntity.class);
        method.setAccessible(true);

        StudentTalentVO result = (StudentTalentVO) method.invoke(studentTalentService, userEntity1);

        // 验证转换结果
        assertNotNull(result, "转换结果不应为null");
        assertEquals(studentId1, result.getStudentId(), "学生ID应该匹配");
        assertEquals("张三", result.getRealName(), "真实姓名应该匹配");
        assertEquals("avatar1.jpg", result.getAvatar(), "头像URL应该匹配");
        assertEquals("清华大学", result.getSchool(), "学校名称应该匹配");
        assertEquals("计算机科学", result.getMajor(), "专业应该匹配");
        assertEquals(1, result.getRanking(), "排名应该匹配");
        assertEquals(150, result.getTotalMajorStudents(), "同专业总人数应该匹配");
        assertNotNull(result.getCoreSubmission(), "核心成果不应为null");
        assertNull(result.getMatchScore(), "匹配分数应该为null");
    }
}